package jp.sinya;

import jp.sinya.proxy.Proxy;
import jp.sinya.proxy.ProxyHandler;
import jp.sinya.proxy.Subject;
import jp.sinya.proxy.TargetSubject;
import jp.sinya.reflect.Person;
import jp.sinya.xml_parse.Dom4JParse;
import jp.sinya.xml_parse.JaxpParse;
import jp.sinya.xml_parse.SaxParse;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Main {
    public static void main(String[] args) {
        testProxyHandler();
    }


    public static void jaxpParseTest() {
        JaxpParse jaxpParse = new JaxpParse();
        jaxpParse.parseTagNameAll("name");
        jaxpParse.parseTagName("age");
        //jaxpParse.addTag("person", "sex", "男");
        //jaxpParse.updateLabel("sex", "女");
        //jaxpParse.deleteLabel("sex");
        jaxpParse.parseAll();
    }

    public static void saxParseTest() {
        SaxParse parse = new SaxParse();
        parse.parse();
    }

    public static void dom4jParseTest() {
        Dom4JParse parse = new Dom4JParse();
        parse.parse();
    }

    /**
     * 反射
     */
    public static void testReflect() {

        try {
            //第一种 通过Class类静态的forName方法
            Class<?> person1 = Class.forName("jp.sinya.reflect.Person");
            System.out.println(person1.toString());//class jp.sinya.reflect.Person

            //第一种 类的class属性
            Class<Person> person2 = Person.class;
            System.out.println(person2.toString());//class jp.sinya.reflect.Person

            //第三种
            Person person3 = new Person();
            Class<? extends Person> person3Class = person3.getClass();
            System.out.println(person3.toString());//Person{age=0, name='null', address='null'}
            System.out.println(person3Class.toString());//class jp.sinya.reflect.Person

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void testReflect2_Field() {

        try {
            Class<?> personClass = Class.forName("jp.sinya.reflect.Person");

            //获取类中的所有成员变量
            Field[] fields = personClass.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                System.out.println(fields[i].getName());// age name address
            }

            //获取类中的public成员变量
            Field[] publicFields = personClass.getFields();
            for (int i = 0; i < publicFields.length; i++) {
                System.out.println(publicFields[i].getName());// age name
            }

            //根据参数名字反射获取参数
            Field addressField = personClass.getDeclaredField("address");
            System.out.println(addressField.getName());// address
            //根据参数名字反射获取参数 public的
            Field ageField = personClass.getDeclaredField("age");
            System.out.println(ageField.getName());// age


        } catch (Exception e) {

        } finally {

        }
    }

    /**
     * 反射 获取函数
     */
    public static void testReflect3_Method() {
        try {
            Class<?> personClass = Class.forName("jp.sinya.reflect.Person");
            Method[] methods = personClass.getDeclaredMethods();
            //获取的所有函数中，不包括构造函数，不包括父类的方法
            for (Method method : methods) {
                System.out.println(method.getName());
            }

            Class<?> manClass = Class.forName("jp.sinya.reflect.Man");
            Method[] manMethods = manClass.getMethods();
            System.out.println();
            //获取的所有函数中，不包括构造函数，但包括父类的方法
            for (Method method : manMethods) {
                System.out.println(method.getName());
            }

            System.out.println();
            //获取指定的public方法，如果有参数的话，需要指定参数类型
            Method sayMethod = personClass.getMethod("say", String.class);
            System.out.println(sayMethod.getName());
            //获取指定的方法，可以是private修饰的
            Method runMethod = personClass.getDeclaredMethod("run");
            System.out.println(runMethod.getName());

        } catch (Exception e) {

        } finally {

        }
    }

    /**
     * 反射 获取构造函数
     */
    public static void testReflect4_Constructor() {
        try {
            Class<?> personClass = Class.forName("jp.sinya.reflect.Person");
            Constructor<?>[] allConstructors = personClass.getDeclaredConstructors();
            Constructor<?>[] publicConstructors = personClass.getConstructors();

            //直接获取指定的构造函数
            Constructor<?> constructor = personClass.getDeclaredConstructor(String.class);
            Constructor<?> publicConstructor = personClass.getConstructor(String.class);


        } catch (Exception e) {

        } finally {

        }
    }

    /**
     * 反射 获取构造函数
     */
    public static void testReflect5_Constructor() {
        try {
            Class<?> personClass = Class.forName("jp.sinya.reflect.Person");

            //判断是否是基础类型
            boolean isPrimitive = personClass.isPrimitive();

            //判断是否是集合类
            boolean isArray = personClass.isArray();

            //判断是否是注解类
            boolean isAnnotation = personClass.isAnnotation();

            //判断是否是接口类
            boolean isInterface = personClass.isInterface();

            //判断是否是枚举类
            boolean isEnum = personClass.isEnum();

            //判断是否是匿名内部类
            boolean isAnonymousClass = personClass.isAnonymousClass();

            //判断是否是 被某个注解类修饰
            boolean isAnnotationPresent = personClass.isAnnotationPresent(Deprecated.class);


            //获取class名字，含包名路径
            String className = personClass.getName();

            //获取class的包信息
            Package packageName = personClass.getPackage();

            //获取Class类名
            String simpleName = personClass.getSimpleName();

            //获取Class访问权限
            int modifiers = personClass.getModifiers();

            //获取内部类
            Class<?>[] declaredClasses = personClass.getDeclaredClasses();

            //获取外部类
            Class<?> declaringClass = personClass.getDeclaringClass();


        } catch (Exception e) {

        } finally {

        }
    }

    /**
     * 反射 操控对象和属性
     */
    public static void testReflect6() {
        //通过newInstance()创建对象
        try {
            Class<?> personClass = Class.forName("jp.sinya.reflect.Person");
            Object obj = personClass.newInstance();
            System.out.println(obj.toString());


            Constructor<?> constructor = personClass.getDeclaredConstructor(String.class);
            Object obj2 = constructor.newInstance("sinya");
            System.out.println();
            System.out.println(obj2.toString());
        } catch (Exception e) {

        } finally {

        }

    }

    /**
     * 基本的静态代理模式
     */
    public static void testProxy() {
        TargetSubject subject = new TargetSubject();
        Proxy p = new Proxy(subject);
        p.request();
    }

    public static void testProxyHandler() {
        //1.创建目标对象
        TargetSubject targetSubject = new TargetSubject();
        //2.创建调用处理器对象
        ProxyHandler handler = new ProxyHandler(targetSubject);
        //3.动态生成代理对象
        Subject proxySubject = (Subject) java.lang.reflect.Proxy.newProxyInstance(//
                TargetSubject.class.getClassLoader(), //
                TargetSubject.class.getInterfaces(), handler);
        //4.通过代理对象调用方法
        proxySubject.request();
    }
}
